﻿/********************************************************************************
** @ Date:2025/04/15
** @ Author: Gaojia
** @ Description: 树管理类，用于管理节点、设备、测点的增删改查和剪贴板操作
** @ Version:1.0.0
** @ Fun:
********************************************************************************/
#ifndef UNodeManager_H
#define UNodeManager_H

#include <QWidget>
#include <QXmlStreamReader>
#include <QStack>
#include "ui_UNodeManager.h"
#include "CBaseNode.h"
#include "CBaseDevice.h"
#include "CMeasurePoint.h"
#include "CNormalNode.h"
#include "CDeviceManager.h"
#include "CPointManager.h"
#include "UAddDevice.h"

enum class EOperationType 
{
	enAdd, 
	enDelete, 
	enMove,
	enReName
};

struct TreeOperation 
{
	EOperationType type;
	CBaseNode* node;             // 操作的节点
	CBaseNode* oldParent;        // 原父节点
	int oldIndex = -1;           // 原位置
	CBaseNode* newParent = nullptr; // 新父节点（用于移动）
	QString oldName;
	QString newName;


	// 多个节点时用
	QVector<CBaseNode*> nodeList;
	QVector<CBaseNode*> oldParents;
	QVector<int> oldIndexes;
	QVector<CBaseNode*> newParents;
	QVector<int> newIndexes;
	// 为了防止内存泄漏，这里不管理 node 的生命周期
};

class UNodeManager : public QWidget
{
	Q_OBJECT

public:
	UNodeManager(QWidget* parent = nullptr);                        // 构造函数
	~UNodeManager();                                                // 析构函数
	void refushUi();                                                // 刷新ui    
	void addNode(CBaseNode* parent);                                // 添加普通节点
	void addDevice(CBaseNode* parent);                              // 添加设备节点
	void addMeasurePoint(CBaseNode* parent);                        // 添加测点节点
	void copyNode(CBaseNode* node);                                 // 复制节点
	void cutNodes(QVector<CBaseNode*> node);                        // 批量剪切节点
	void pasteNodes(CBaseNode* targetParent);                       // 批量粘贴节点
	void deleteNode(CBaseNode* node);                               // 删除节点
	void redo();                                                    //重做
	void undo();                                                    //撤销
	void initUI();                                                  // 初始化界面
	void setCurrNode(CBaseNode* node, CBaseNode* child = nullptr);  //设置当前选中的节
	void onTreeLeftClieck(const QPoint& pos);                       // 左键点击事件
private:
	void showContextMenu(CBaseNode* node, const QPoint& globalPos); // 显示右键菜单
	void showContextLeft(CBaseNode* node, const QPoint& globalPos); // 鼠标左键响应
	void connectTree();                                             // 连接信号槽
	void createNullMenu(const QPoint& globalPos);                   // 创建空白处点击菜单
	void createRootMenu(QMenu* menu, CBaseNode* node);              // 创建根节点菜单
	void createNodeMenu(QMenu* menu, CBaseNode* node);              // 创建普通节点菜单
	void createDeviceMenu(QMenu* menu, CBaseNode* node);            // 创建设备菜单
	void createPointMenu(QMenu* menu, CBaseNode* node);             // 创建测点菜单
	void keyPressEvent(QKeyEvent* event);                           // 键盘事件处理
	QVector<CBaseNode*> getSelectedNodes();                         // 获取多选的项
	bool isDescendant(CBaseNode* parent, CBaseNode* child);         // 判断child是不是parent的子节点
	void mousePressEvent(QMouseEvent *event);
	void refushNode(CBaseNode * node, int nType = 0);                              //刷新节点
	void refushMenu();//刷新菜单
protected:
	bool eventFilter(QObject *obj, QEvent *event) override;
	void onTreeRightClieck(const QPoint& pos);                     // 右键点击事件
private:
	Ui::UNodeManagerClass ui;                                       // UI界面
	CBaseNode* rootNode;                                            // 根节点
	QStandardItemModel* model;                                      // 树模型
	UAddDevice* m_pUAddDevice;                                      // 添加设备窗口
	CPointManager* m_pointManager;                                  // 测点管理器
	QVector<CBaseNode*> m_pVecClipboardNode;                        // 剪贴板节点
	bool m_isCutOperation = false;                                  // 是否为剪切操作
	QStack<TreeOperation> m_undoStack;                              // 上一步数组
	QStack<TreeOperation> m_redoStack;                              // 下一步数组
	QWidget *m_pConfig;
	CBaseNode * m_pNodeCurr;                                        //当前选择的节点
	CBaseNode* m_pNodeChild;                                        //当前选择的节点在右边页面的子节点
public slots :
	void onTreeContextMenuRequested(const QPoint& pos);             // 请求右键菜单槽
	void renameNode(CBaseNode* node);                               // 重命名节点槽
	void slot_addNode();
	void slot_addPage();
	void slot_addPoint();
	void slot_deleteNode();
signals:
	void sign_showCilckedWidget(CBaseNode *pNode, CBaseNode* pchild=nullptr);
};

#endif                                                              // UNodeManager_H
